package controllers.administrator;

import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import services.AdministratorService;
import services.EventService;
import controllers.AbstractController;
import domain.Event;
import domain.Route;

@Controller 
@RequestMapping("/event/administrator")
public class EventAdministratorController extends AbstractController {

	// Services

	@Autowired
	private EventService eventService;
	@Autowired
	private AdministratorService administratorService;

	// Constructors

	public EventAdministratorController() {
		super();
	}

	// Listing

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView list() {
		ModelAndView result;
		Collection<Event> events = eventService.findEventsByAdministrator();

		result = new ModelAndView("event/list");
		result.addObject("requestURI", "event/administrator/list.do");
		result.addObject("events", events);
		result.addObject("backURI", "/welcome/index.do");
		return result;
	}

	@RequestMapping(value = "/ongoing/list", method = RequestMethod.GET)
	public ModelAndView ongoingList() {
		ModelAndView result;
		Collection<Event> events;
		events = eventService.findEventsOngoingByAdministrator();

		result = new ModelAndView("event/list");
		result.addObject("requestURI", "event/administrator/ongoing/list.do");
		result.addObject("events", events);
		result.addObject("backURI", "/welcome/index.do");
		return result;
	}

	@RequestMapping(value = "/ordered/list", method = RequestMethod.GET)
	public ModelAndView orderedList() {
		ModelAndView result;

		Collection<Event> events = eventService
				.findByAdministratorOrderedByRating(administratorService
						.findByPrincipal().getId());

		result = new ModelAndView("event/list");
		result.addObject("requestURI", "event/list.do");
		result.addObject("events", events);
		result.addObject("ordered", true);
		result.addObject("backURI", "/welcome/index.do");
		return result;
	}

	// Creation
	@RequestMapping(value = "/create", method = RequestMethod.GET)
	public ModelAndView create() {
		ModelAndView result;
		Event event = eventService.create();

		Boolean isNew = true;
		Boolean isOwner = false;
		Boolean editable = true;

		List<String> currencies = new LinkedList<String>();
		currencies.add("Euros");
		currencies.add("Dollars");
		currencies.add("Pounds");

		result = new ModelAndView("event/edit");
		result.addObject("event", event);
		result.addObject("currencies", currencies);
		result.addObject("requestURI", "event/administrator/edit.do");
		result.addObject("isNew", isNew);
		result.addObject("isOwner", isOwner);
		result.addObject("editable", editable);
		result.addObject("backURI", "/welcome/index.do");

		return result;

	}

	// Edition
	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public ModelAndView edit(@RequestParam int eventId) {
		ModelAndView result;
		Date currentMoment = new Date();
		Event event;
		event = eventService.findOne(eventId);
		Assert.notNull(event);
		Boolean isNew = false;
		Boolean isOwner = event.getAdministrator().equals(
				administratorService.findByPrincipal());
		Boolean editable = event.getStartMoment().after(currentMoment) && event.getRegistrations().isEmpty();
		Boolean emptyChallenges= event.getChallenges().isEmpty();
		
		result = new ModelAndView("event/edit");
		result.addObject("event", event);
		result.addObject("requestURI", "event/administrator/edit.do");
		result.addObject("emptyChallenges",emptyChallenges);
		result.addObject("isNew", isNew);
		result.addObject("isOwner", isOwner);
		result.addObject("editable", editable);
		result.addObject("backURI", "/welcome/index.do");
		

		return result;

	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST, params = "save")
	public ModelAndView save(@Valid Event event, BindingResult binding) {
		ModelAndView result;
		Date currentMoment = new Date();
		Boolean isNew = false;
		Boolean isOwner = event.getAdministrator().equals(
				administratorService.findByPrincipal());
		Boolean editable = event.getStartMoment().after(currentMoment) 
				&& event.getRegistrations().isEmpty();
		Boolean emptyChallenges = event.getChallenges().isEmpty();

		if (binding.hasErrors()) {
			result = createEditModelAndView(event);
		} else {
			try {
				eventService.save(event);
				result = new ModelAndView("redirect:list.do");
			} catch (Throwable oops) {
				result = createEditModelAndView(event, "event.commit.error");
			}
		}
		result.addObject("emptyChallenges",emptyChallenges);
		result.addObject("isNew", isNew);
		result.addObject("isOwner", isOwner);
		result.addObject("editable", editable);
		result.addObject("backURI", "/welcome/index.do");
		return result;

	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST, params = "delete")
	public ModelAndView delete(Event event, BindingResult binding) {
		ModelAndView result;
		Date currentMoment = new Date();
		Boolean isNew = false;
		Boolean isOwner = event.getAdministrator().equals(
				administratorService.findByPrincipal());
		Boolean editable = event.getStartMoment().after(currentMoment) 
				&& event.getRegistrations().isEmpty();
		Boolean emptyChallenges = event.getChallenges().isEmpty();
		List<Route> routes = new LinkedList<Route>();
		event.setRoutes(routes);

		try {
			
			eventService.delete(event);
			result = new ModelAndView("redirect:list.do");
		} catch (Throwable oops) {
			result = createEditModelAndView(event, "event.commit.error");
		}
		
		result.addObject("emptyChallenges",emptyChallenges);
		result.addObject("isNew", isNew);
		result.addObject("isOwner", isOwner);
		result.addObject("editable", editable);
		result.addObject("backURI", "/welcome/index.do");
		return result;

	}

	// Ancillary methods

	protected ModelAndView createEditModelAndView(Event event) {
		ModelAndView result;
		result = createEditModelAndView(event, null);
		return result;

	}

	protected ModelAndView createEditModelAndView(Event event, String message) {
		ModelAndView result;

		result = new ModelAndView("event/edit");
		result.addObject("event", event);
		result.addObject("message", message);

		return result;

	}

}
